package com.chart.web.controller.weather;
import com.chart.common.core.domain.AjaxResult;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPInputStream;
import static com.chart.common.constant.CacheConstants.WEATHER_IP;

@RestController
@RequestMapping("system")
public class WeatherController {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 和风天气服务
     */
    private String apiToken = "81514dff66fa4e1a82b6123f06fcb0b0";  // 替换为你的API密钥
    private static final String AURL = "https://devapi.qweather.com/v7/weather/now";


    /**
     * 百度ip定位
     */
    private static final String API_URL = "https://api.map.baidu.com/location/ip?";
    private static final String AK = "cfne0IDH4FDyJabdFlXGsfOrw6fcq5Xq"; // 替换为您的百度地图开发者密钥




    /**
     * 获取实时天气信息，根据请求 IP 自动定位
     * @param request HttpServletRequest，用于获取请求的 IP 地址
     * @return 天气信息
     */
    @GetMapping("/weather/now")
    public AjaxResult getWeather(HttpServletRequest request) {
        try {
            // 获取客户端 IP 地址
            String clientIp = getClientIp(request);
            if (clientIp == null) {
                System.out.println("获取的ip"+clientIp);
                return new  AjaxResult(620,"无法获取客户端 IP 地址") ;
            }

            String redisKey = WEATHER_IP  + clientIp;
            // 2. 使用相同的 redisKey 来检查缓存数据
            Object cachedDataObject = redisTemplate.opsForValue().get(redisKey);
            if (cachedDataObject != null && cachedDataObject instanceof JsonNode) {
                JsonNode cachedData = (JsonNode) cachedDataObject;
                return AjaxResult.success(cachedData); // 如果缓存存在，直接返回缓存的数据
            }


            // 调用 IP 定位服务获取位置信息
            String location = getLocationFromIp(clientIp);
            if (location == null) {
                System.out.println("获取的位置"+clientIp);
                return  new AjaxResult( 621,"无法根据 IP 地址获取位置") ;
            }

            // 构造完整的天气 API 请求 URL
            String requestUrl = AURL + "?location=" + location + "&key=" + apiToken;

            // 创建 URL 对象并发送 HTTP 请求
            URL url = new URL(requestUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Accept-Encoding", "gzip");
            connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");

            // 获取响应
            int responseCode = connection.getResponseCode();
            if (responseCode == 200) {
                // 如果响应是 Gzip 格式，则需要解压缩
                BufferedReader reader;
                if ("gzip".equals(connection.getContentEncoding())) {
                    reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(connection.getInputStream())));
                } else {
                    reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                }

                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                reader.close();

                // 使用 ObjectMapper 解析 JSON
                ObjectMapper objectMapper = new ObjectMapper();
                JsonNode rootNode = objectMapper.readTree(response.toString());
                String code = rootNode.get("code").asText();

                if ("200".equals(code)) {
                    JsonNode now = rootNode.get("now");
                    // 将获取的天气数据缓存到 Redis，缓存时间为 30 分钟
                    redisTemplate.opsForValue().set(redisKey, now, 30, TimeUnit.MINUTES);  // 将获取的天气数据缓存到 Redis，缓存时间为 30 分钟
                    return AjaxResult.success(now);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();

        }
        return null;
    }












    /**
     * 获取客户端的 IP 地址
     * @param request HttpServletRequest
     * @return 客户端 IP 地址
     */
    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * 调用 IP 定位服务获取地理位置信息
     * @param ip 客户端 IP 地址
     * @return 城市 ID (location) 或 null 如果失败
     */
    private String getLocationFromIp(String ip) throws Exception {
            // 构建请求参数
            Map<String, String> params = new LinkedHashMap<>();
            params.put("ip", ip); // 如果为空，则默认获取请求方的 IP
            params.put("coor", "bd09ll"); // 坐标类型
            params.put("ak", AK); // 开发者密钥

            // 发起 API 调用
            String response = requestGet(API_URL, params);

            // 解析 JSON 数据，提取 adcode
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode rootNode = objectMapper.readTree(response);

            JsonNode contentNode = rootNode.path("content");
            JsonNode addressDetailNode = contentNode.path("address_detail");
            String adcode = addressDetailNode.path("adcode").asText();
            String cityCode = addressDetailNode.path("city_code").asText();
            JsonNode pointNode = contentNode.path("point");
            // 格式化 X 和 Y 坐标保留两位小数
            DecimalFormat df = new DecimalFormat("#.##");
            String x = df.format(pointNode.path("x").asDouble());
            String y = df.format(pointNode.path("y").asDouble());



        String xy=x+","+y;





        return xy;
    }

    /**
     * 模拟从城市名称获取城市 ID
     * @param city 城市名称
     * @return 城市 ID
     */
    private String getCityCode(String city) {
        // 模拟城市名称与 ID 的映射
        if ("Shanghai".equalsIgnoreCase(city)) {
            return "101020100"; // 上海
        }
        // 添加更多城市映射
        return null;
    }

    /**
     * 调用百度地图 API
     *
     * @param strUrl 请求的基础 URL
     * @param params 请求的参数
     * @return API 返回的 JSON 数据
     * @throws Exception 异常捕获
     */
    private String requestGet(String strUrl, Map<String, String> params) throws Exception {
        // 构建完整 URL
        StringBuilder queryString = new StringBuilder(strUrl);
        for (Map.Entry<String, String> entry : params.entrySet()) {
            queryString.append(entry.getKey())
                    .append("=")
                    .append(UriUtils.encode(entry.getValue(), "UTF-8"))
                    .append("&");
        }
        if (queryString.length() > 0) {
            queryString.deleteCharAt(queryString.length() - 1); // 移除最后一个多余的 "&"
        }

        // 发起 HTTP 请求
        URL url = new URL(queryString.toString());
        HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
        httpConnection.setRequestMethod("GET");

        // 读取响应
        InputStreamReader isr = new InputStreamReader(httpConnection.getInputStream(), "UTF-8");
        BufferedReader reader = new BufferedReader(isr);
        StringBuilder response = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            response.append(line);
        }
        reader.close();
        isr.close();

        return response.toString();
    }
}
